<template>
	  <div class="page_root" data-page-name="项目类型管理" data-page-identification="w_ut872as0pg">
	    <a-spin :spinning="spinning">
	      <a-form ref="formRef" :model="formState" :layout="layout" :label-align="labelAlign" :label-col="labelCol" :wrapper-col="wrapperCol" style="height: 100%">
	        <div style="height: 100%; display: flex; flex-direction: column; width: 100%">
	          <div style="height: 100%;overflow:auto;">
	            <!-- begin vid_fk663mkxbc 布局容器_i76sisttsj -->
	            <div :style="{width: '100%',padding: '0 0px'}">
	              <a-row
	                v-if="showState.vid_fk663mkxbc_visible"
	                ref="vid_fk663mkxbc_ref"
	                class="vid_fk663mkxbc"
	                :gutter="vid_fk663mkxbc_props.gutter"
	                :slots="vid_fk663mkxbc_props.slots"
	                :justify="vid_fk663mkxbc_props.justify"
	                :align="vid_fk663mkxbc_props.align"
	              >
	                <a-col :span="24">
	                  <!-- begin vid_1nr5wvit51 基础数据字典管理 -->
	                  <al-divider
	                    v-if="showState.vid_1nr5wvit51_visible"
	                    ref="vid_1nr5wvit51_ref"
	                    class="vid_1nr5wvit51"
	                    :title="vid_1nr5wvit51_props.title"
	                    :gradualChange="vid_1nr5wvit51_props.gradualChange"
	                    :titleColor="vid_1nr5wvit51_props.titleColor"
	                    :backgroundColor="vid_1nr5wvit51_props.backgroundColor"
	                    :disabled="vid_1nr5wvit51_props.disabled"
	                  >
	                  </al-divider>
	                  <!-- end vid_1nr5wvit51 基础数据字典管理 -->
	                </a-col>
	              </a-row>
	            </div>
	            <!-- end vid_fk663mkxbc 布局容器_i76sisttsj -->
	            <a-form-item v-if="showState.vid_an9hbtzda7_visible" name="data_type">
	              <template v-slot:label> 类型 </template>
	              <!-- begin vid_an9hbtzda7 data_type -->
	              <a-select
	                v-if="showState.vid_an9hbtzda7_visible"
	                ref="vid_an9hbtzda7_ref"
	                class="vid_an9hbtzda7"
	                :allowClear="vid_an9hbtzda7_props.allowClear"
	                :showSearch="vid_an9hbtzda7_props.showSearch"
	                :filterOption="vid_an9hbtzda7_props.filterOption"
	                v-model:value="formState.data_type"
	                :bordered="vid_an9hbtzda7_props.bordered"
	                :options="vid_an9hbtzda7_options"
	                :disabled="vid_an9hbtzda7_props.disabled"
	              >
	              </a-select>
	              <!-- end vid_an9hbtzda7 data_type -->
	            </a-form-item>
	            <a-form-item v-if="showState.vid_ya7ylgye55_visible" name="data_value">
	              <template v-slot:label> 值 </template>
	              <!-- begin vid_ya7ylgye55 data_value -->
	              <a-input
	                v-if="showState.vid_ya7ylgye55_visible"
	                ref="vid_ya7ylgye55_ref"
	                class="vid_ya7ylgye55"
	                :allowClear="vid_ya7ylgye55_props.allowClear"
	                v-model:value="formState.data_value"
	                :comparisonTips="vid_ya7ylgye55_props.comparisonTips"
	                :placeholder="vid_ya7ylgye55_props.placeholder"
	                :bordered="vid_ya7ylgye55_props.bordered"
	                :disabled="vid_ya7ylgye55_props.disabled"
	              >
	              </a-input>
	              <!-- end vid_ya7ylgye55 data_value -->
	            </a-form-item>
	          </div>
	          <div v-if="!isProcess" style="text-align: center">
	            <a-button type="primary" :loading="submitLoading" @click="onSubmit">{{ props.editType === 'edit' ? '保存' :  isProcessForm ? '发起流程': '提交'}}</a-button>
	          </div>
	        </div>
	      </a-form>
	    </a-spin>
	  </div>
	</template>
	<script setup>
	  
import {
  h, ref, reactive, toRaw, markRaw, watch, computed,
  onBeforeMount, onMounted, onBeforeUnmount, onUnmounted, onActivated, onDeactivated
} from "vue";
import { useRoute, useRouter } from 'vue-router';
const router = useRouter();
const route = useRoute();
import { get, post, put, del, request } from '@/utils/http/Axios';
import { cloneDeep, isNullOrEmpty, isEmptyArr, isNullOrUnDef, localGet, isContained, isArray, isEmpty, merge, getDifferenceArray, isObject, traversalTreeStructure, checkCaseCondition } from '@/utils/index';
import dayjs from 'dayjs';
import weekday from 'dayjs/plugin/weekday';
import weekOfYear from 'dayjs/plugin/weekOfYear';
import LocaleData from 'dayjs/plugin/localeData';
dayjs.extend(weekday);
dayjs.extend(weekOfYear);
dayjs.extend(LocaleData);
import { getPagePcChartsDataSourceConvert } from '@/utils/chart';

import { message, notification, Modal } from 'ant-design-vue'
const immediateWatch = (source, callback) => {
  watch(source, callback, {deep: true,immediate: true })
}
// ---------------------------- 事件定义 ----------------------------
const emit = defineEmits(['saveSuccess'])
// ============================ 事件定义 ============================

// ---------------------------- 属性定义 ----------------------------
const props = defineProps({
    id: {
        type: Number,
        required: false
    },
    editType: {
        type: String,
        required: false,
        default() {
            return 'create'
        }
    },
    isProcess: {
      type: Boolean,
      required: false,
      default() {
        return false;
      },
    },
    formData: {
        type: Object,
        required: false
    },
    
})

const vid_fk663mkxbc_props = reactive({
    gutter: 0,
    slots: "24",
    justify: undefined,
    align: undefined,
})
    

const vid_1nr5wvit51_props = reactive({
    disabled: false,
    title: "基础数据字典管理",
    systemInputStatus: "normal",
    gradualChange: {"config":{"fontSize":"14px","borderRadius":"0 0 0 0"},"gradualChange":"normal","borderBottom":""},
    titleColor: "#3875FF",
    backgroundColor: "#EBF1FF",
})
    

const vid_an9hbtzda7_props = reactive({
    allowClear: true,
    showSearch: true,
    filterOption: (input, option) => {
    return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0;
  },
    disabled: false,
    systemLabel: "类型",
    bordered: true,
    fieldKey: "data_type",
    systemHideLabel: false,
    systemTooltip: undefined,
    systemInputStatus: "normal",
    systemCommitData: true,
    systemDefaultValueType: "custom",
    systemValue: undefined,
    systemDataLinkage: undefined,
    systemCalculation: undefined,
    systemRules: undefined,
    systemOptionType: "custom",
    systemOptions: [{"label":"项目类型","selected":false,"value":"uf85xc850y"},{"label":"其他","selected":false,"value":"l5alf5rwu5"}],
    systemAssociateOtherForms: undefined,
    systemDictionary: undefined,
})
    

const vid_ya7ylgye55_props = reactive({
    allowClear: true,
    disabled: false,
    systemLabel: "值",
    fieldKey: "data_value",
    systemHideLabel: false,
    systemTooltip: undefined,
    systemInputStatus: "normal",
    systemDefaultValueType: "custom",
    systemValue: undefined,
    systemDataLinkage: undefined,
    systemCalculation: undefined,
    systemCommitData: true,
    comparisonTips: [],
    systemRules: undefined,
    placeholder: undefined,
    bordered: true,
})
    

const componentPropsMap = {
    vid_fk663mkxbc_props,
    vid_1nr5wvit51_props,
    vid_an9hbtzda7_props,
    vid_ya7ylgye55_props
};
  
// ============================ 属性定义 ============================

// ---------------------------- 元素数据引用 ----------------------------
// 表单数据加载状态
const spinning = ref(true)
// 表单的引用
const formRef = ref()
// 组件 布局容器_i76sisttsj ref 的引用
const vid_fk663mkxbc_ref = ref(null);
// 组件 基础数据字典管理 ref 的引用
const vid_1nr5wvit51_ref = ref(null);
// 组件 data_type ref 的引用
const vid_an9hbtzda7_ref = ref(null);
// 组件 data_value ref 的引用
const vid_ya7ylgye55_ref = ref(null);
// 动态key的map
const mixedTypeKeyMap = {"data_type":"OPTIONS"};
// 单选框组件动态key集合
const radioGroupMixedTypeKeys = [];
const vid_an9hbtzda7_options = ref(
[{"label":"项目类型","selected":false,"value":"uf85xc850y"},{"label":"其他","selected":false,"value":"l5alf5rwu5"}]
)

const optionsRef = reactive({
    vid_an9hbtzda7_options
});
  
const showState = reactive({
    vid_fk663mkxbc_visible: true,
    vid_1nr5wvit51_visible: true,
    vid_an9hbtzda7_visible: true,
    vid_ya7ylgye55_visible: true,
})
// ============================ 元素数据引用 ============================

// ---------------------------- 数据 ----------------------------
const formName = '项目类型管理';
const applicationId = 50000005;
const pageId = 50000753;
// 当前表单是否绑定了流程
const isProcessForm = ref(false);
const submitLoading = ref(false);
const subFormMap = null
const userInfo = localGet('al__USER_INFO')
const labelCol = {}
const wrapperCol = {}
// horizontal | vertical
const layout = "vertical"
// left | right
const labelAlign = "left"
const formState = reactive({
    data_type: "",
    data_value: undefined,
})

const fieldKeyMap = {"data_type":"vid_an9hbtzda7","data_value":"vid_ya7ylgye55"};

const rules = {
}
// ============================ 数据 ============================

// ---------------------------- 方法 ----------------------------

// 处理校验
const setSubFormName =(parentInfo, name)=>{
  return [parentInfo.parents, parentInfo.index, name];
}
// 处理提交校验
const handleSubmitVerify = async function(){
  // 引入公式校验的参数
  const submitRulesMap = [];
  // 校验公式计算结果
  let ruleVerifyResult = submitRulesMap.every(result => {
    return result();
  });
  // 如果未通过通过公式，不再进行联合唯一校验
  if(!ruleVerifyResult){
    return ruleVerifyResult;
  }
  // 通过公式校验后，进行联合唯一校验
  let uniqueKeyVerifyResult = true;
  const submitUniqueKeyResponse = await Promise.all([]);
  const submitUniqueKeyTipsMap = [];
  submitUniqueKeyResponse.forEach((item, index) => {
    if (item.data) { // 重复了
      uniqueKeyVerifyResult = false; // 重置标志位
      message.error(submitUniqueKeyTipsMap[index]); // 弹出错误提示
    }
  });
  
  return uniqueKeyVerifyResult;
};

// 获取选项值类型的option对象
const getOptionByValue = (list, value) => {
  if (!value) {
    // 用于过滤空值
    return void 0;
  }
  let option;
  traversalTreeStructure(list, (item) => {
    if (value == item.value) {
      option = {
        value: item.value,
        label: item.label,
        title: item.title,
      };
    }
    return item;
  });
  return option ? option : value;
};

const setMixedTypeValue = (key, value)=>{
  if(mixedTypeKeyMap && mixedTypeKeyMap[key]){
    // 兼容用户/部门组件值可能为字符串/数组的情况
    if (mixedTypeKeyMap[key] === 'ARRAY' && !Array.isArray(value) && value) {
      return [value]
    } else if (mixedTypeKeyMap[key] === 'OPTIONS') {
      if (Array.isArray(value)) {
        // 表单重置之后级联选择器的值为[''], 导致存值错误，故放弃使用map方法，改为手动push数组
        const arr = [];
        value.forEach(item => {
          if (item) {
            arr.push(getOptionByValue(optionsRef[`${fieldKeyMap[key]}_options`], item));
          }
        });
        return arr;
      } else {
        const singleValue = getOptionByValue(optionsRef[`${fieldKeyMap[key]}_options`], value);
        return singleValue ? [singleValue] : [];
      }
    }
    return value;
  }
  return value;
}
// 重置表单
const resetForm = () => {
  try {
    formRef.value?.resetFields && formRef.value.resetFields();
  } catch (error) {
    console.log('resetForm:', error)
  }
};
// 清除缓存
const clearCache = () => {
  localStorage.removeItem('from_cache_w_ut872as0pg_' + props.editType);
};
// 获取提交参数
const getParams = (formModal = toRaw(formState)) => {
  const bodyConfig = [];
  const childrenList = [];
  Object.keys(formModal).forEach(key=>{
    // 是子表单
    if(subFormMap && subFormMap[key]){
      formModal[key].forEach(subformItem=>{
        const childrenListItem = {
          pageId: subFormMap[key],
          bodyConfig: [],
          childrenList: []
        }
        // 如果有子表单数据
        if(subformItem){
          Object.keys(subformItem).forEach(childKey=>{
            if (childKey === "id") {
              childrenListItem.id = subformItem[childKey]
            } else {
              // 子表单数据转成期望的格式
              childrenListItem.bodyConfig.push({ 
                key: childKey,
                value: setMixedTypeValue(childKey, subformItem[childKey])
              })
            }
          })
        }
        childrenList.push(childrenListItem)
      })
    }else if(JSON.stringify(formModal[key]) !== '[{}]'){ // 舍弃空子表单提交
      bodyConfig.push({
        key,
        value: setMixedTypeValue(key, formModal[key])
      }) 
    }
  })
  return {
    pageId,
    applicationId,
    processInstanceName: formName,
    bodyConfig,
    // 处理子表单
    childrenList
  };
};

// 为了更好实现诸多需求，将提交校验逻辑，组装数据逻辑，调用接口逻辑进行解耦
const handleSubmit = async (submitDataFn) => {
  const formModal = toRaw(formState);
  await formRef.value?.validateFields();
  const submitResult = await handleSubmitVerify();
  if(!submitResult){
    return;
  }
  if(props.editType === 'create') {
    const data = {"serialNumberIdList":[],"pageData":{}};
    const serialNumberIdComponentIdMap = {};
    if (data.serialNumberIdList.length > 0) {
      const res = await post('/taishan-runtime/api/v3/component/serial_number/data', data);
      res.data ??= [];
      res.data.forEach(rule => {
        const fieldKey = serialNumberIdComponentIdMap[rule.serialNumberId];
        // 取出根据规则生成的流水号并赋值
        formModal[fieldKey] = rule.value;
        // TODO: 容器，子表单内存在流水号可能有问题。待检查。
      });
    }
    const params = getParams(formModal);
    params.triggerAction = 'CREATE';
    submitDataFn(params, post);
  } else {
    const params = getParams(formModal);
    params.id = props.id;
    params.triggerAction = 'EDIT';
    params.pageDataIdList = [props.id];
    submitDataFn(params, put);
  }
}
// 处理表单提交逻辑
const onSubmit = async function () {
  submitLoading.value = true;
  handleSubmit((params, requestMethod) => {
    requestMethod('/taishan-runtime/api/v4/page_data', params).then((res) => {
      if (res.status === 'success') {
        message.success("数据提交成功");
        resetForm();
        emit('saveSuccess');
        // 清除缓存
        clearCache();
      } else {
        message.error(res.errorMsg || "数据提交失败");
      }
    }).finally(() => {
      submitLoading.value = false;
    });
  });
};
const controlFormItemVisible = (filedKey, visible) => {
    showState[`${fieldKeyMap[filedKey]}_visible`] = visible
}

const controlFormItemDisabled = (filedKey, disabled) => {
    componentPropsMap[`${fieldKeyMap[filedKey]}_props`].disabled = disabled
}
// Expose部分函数供外包调用
defineExpose({ formRef, formState, controlFormItemVisible, controlFormItemDisabled, getParams, handleSubmit, onSubmit, resetForm, clearCache });




// 公式计算处理策略函数
const formulaStrategy = {
  IF: (condition,first,second) => condition ? first : second,
  DATE: (serial_number) => dayjs(serial_number).format("YYYY-MM-DD"),
  DAY: (serial_number) => dayjs(serial_number).date(),
  HOUR: (serial_number) => dayjs(serial_number).hour(),
  MINUTE: (serial_number) => dayjs(serial_number).minute(),
  MONTH: (serial_number) => dayjs(serial_number).month() + 1,
  NOW: () => dayjs().format('YYYY-MM-DD HH:mm:ss'),
  SECOND: (serial_number) => dayjs(serial_number).second(),
  DATE_PARSE: (serial_number, format = 'YYYY-MM-DD HH:mm:ss') => dayjs(serial_number).format(format),
  CURRENT_DATE: () => dayjs().format('YYYY-MM-DD'),
  WEEK: (serial_number) => dayjs(serial_number).week(),
  DAY_OF_WEEK: (serial_number) => dayjs(serial_number).day(),
  YEAR: (serial_number) => dayjs(serial_number).year(),
  ABS: (number) => Math.abs(number),
  TRUNCATE: (number) => Math.floor(number),
  GREATEST: (...args) => Math.max(...args),
  LEAST: (...args) => Math.min(...args),
  CONCAT: (...args) => args.join(''),
  LOWER: (text = '') => text.toLowerCase(),
  UPPER: (text = '') => text.toUpperCase(),
  LEFT: (text = '', num_chars = 1) => text.slice(0, num_chars),
  RIGHT: (text = '', num_chars = 1) => text.slice(-num_chars),
}

// ============================ 方法 ============================

// ---------------------------- 生命周期 ----------------------------

onMounted(() => {
    
    // 过滤子表单字段
    const filterSubformField = (dataList) => {
      return dataList && dataList.map(item =>{
        Object.keys(item).forEach(field => {
          if(field !== "id" && !fieldKeyMap.hasOwnProperty(field)){
            delete item[field]
          }
        });
        return item;
      })
    }
    // 处理选项值类型组件的回显值问题
    const getMixedTypeValue = (data, key) => {
      if (isObject(data) && data.hasOwnProperty('dataList')) {
        return filterSubformField(data.dataList)
      }
      // 选项值类型组件的数据是一组option对象 [{label: '', value: ''}]
      if (Array.isArray(data) && mixedTypeKeyMap && mixedTypeKeyMap[key] && mixedTypeKeyMap[key] === 'OPTIONS') {
        // 单选组件选中的值是string类型
        if(radioGroupMixedTypeKeys.includes(key)) {
          return data[0].value
        }
        return data.map(item => item.value)
      }
      return data
    }
    // 获取数据
    post('/taishan-runtime/api/v2/process_definition/search',{
      filter: {
        pageId,
        applicationId,
      },
      sort: {
        field: 'createdDate',
        direction: 'DESC'
      },
      pageNo: 1,
      pageSize: 10
    }).then(({ data }) => {
      isProcessForm.value = data?.content?.length > 0;
    });
    // 根据表单编辑类型，加载数据
    if (props.editType === 'create') {
        spinning.value = false
    } else if (props.formData) {
      Object.keys(formState).forEach(key => {
          if (props.formData.hasOwnProperty(key)) {
              formState[key] = getMixedTypeValue(props.formData[key], key)
          }
      })
      spinning.value = false
    } else {
        post('/taishan-runtime/api/v4/page_data/detail', {
            id: props.id,
            pageId: pageId,
            bodyConfig: [
                {
                    key: ''
                }
            ]
        }).then(resp => {
            const { data } = resp;
            if (data && data.dataList && data.dataList.length > 0) {
                const result = data.dataList[0]
                Object.keys(formState).forEach(key => {
                    if (result.hasOwnProperty(key)) {
                      formState[key] = getMixedTypeValue(result[key], key)
                    }
                })
            }
            
        }).finally(() => {
            spinning.value = false
        })
    }
    // 加载数据字典数据
    
    // 加载其他表单数据
    
    // 从接口加载某些数据
    
})

// ============================ 生命周期 ============================

// ---------------------------- 数据关联处理 ----------------------------




// ============================ 数据关联处理 ============================


// ================================定制化逻辑========================================
	</script>
	<style lang="less" scoped>
	  .page_root {
width: 100%;
height: 100%;
overflow: auto;
}
.page_root :deep(.@{ant-prefix}-spin-nested-loading),
.page_root :deep(.@{ant-prefix}-spin-container)
 {
    height: 100%;
}
/* 穿梭框改变默认样式，为根据组件样式控制左右栏宽度。 */
:deep(.@{ant-prefix}-transfer-list)
 {
    height: 100%;
    width: 50%;
}

/** 表格操作列单元格的样式 */
.operation-cell {
  margin: -16px;
}
	</style>